<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Process</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>Process</h1>

<p>Performs one of the following operations on a process: checks if it exists; changes its priority; closes it; waits for it to close.</p>

<pre class="Syntax">Process, Cmd [, PID-or-Name, Param3]</pre>
<h3>Parameters</h3>
<dl>

  <dt>Cmd</dt>
  <dd><p>One of the following words:</p>
    <p><strong>Exist</strong>: Sets <a href="../misc/ErrorLevel.htm">ErrorLevel</a> to the Process ID (PID) if a matching process exists, or 0 otherwise.  If the <em>PID-or-Name</em> parameter is blank, the script's own PID is retrieved. An alternate, single-line method to retrieve the script's PID is <code>PID := DllCall(&quot;GetCurrentProcessId&quot;)</code>.</p>
    <p><strong>Close</strong>: If a matching process is successfully terminated, <a href="../misc/ErrorLevel.htm">ErrorLevel</a> is set to its former Process ID (PID). Otherwise (there was no matching process or there was a problem terminating it), it is set to 0. Since the process will be abruptly terminated -- possibly interrupting its work at a critical point or resulting in the loss of unsaved data in its windows (if it has any) -- this method should be used only if a process cannot be closed by using <a href="WinClose.htm">WinClose</a> on one of its windows.</p>
    <p><strong>List</strong>: Although <em>List</em> is not yet supported, the <a href="#ListEx">examples section</a> demonstrates how to retrieve a list of processes via DllCall.</p>
    <p><strong><a name="Priority"></a>Priority</strong>: Changes the priority (as seen in Windows Task Manager) of the first matching process to <em>Param3</em> and sets <a href="../misc/ErrorLevel.htm">ErrorLevel</a> to its Process ID (PID). If the <em>PID-or-Name</em> parameter is blank, the script's own priority will be changed. If there is no matching process or there was a problem changing its priority, ErrorLevel is set to 0.</p>
    <p><em>Param3</em> should be one of the following letters or words: L (or Low), B (or BelowNormal), N (or Normal), A (or AboveNormal), H (or High), R (or Realtime). Note: Any process not designed to run at Realtime priority might reduce system stability if set to that level.</p>
    <p><strong>Wait</strong>: Waits up to <em>Param3</em> seconds (can contain a decimal point) for a matching process to exist. If <em>Param3</em> is omitted, the command will wait indefinitely. If a matching process is discovered, <a href="../misc/ErrorLevel.htm">ErrorLevel</a> is set to its Process ID (PID). If the command times out, ErrorLevel is set to 0.</p>
    <p><strong>WaitClose</strong>: Waits up to <em>Param3</em> seconds (can contain a decimal point) for ALL matching processes to close. If <em>Param3</em> is omitted, the command will wait indefinitely. If all matching processes are closed, <a href="../misc/ErrorLevel.htm">ErrorLevel</a> is set to 0. If the command times out, ErrorLevel is set to the Process ID (PID) of the first matching process that still exists.</p></dd>

  <dt>PID-or-Name</dt>
  <dd><p>This parameter can be either a number (the PID) or a process name as described below. It can also be left blank to change the priority of the script itself.</p>
      <p>PID: The Process ID, which is a number that uniquely identifies one specific process (this number is valid only during the lifetime of that process). The PID of a newly launched process can be determined via the <a href="Run.htm">Run</a> command. Similarly, the PID of a window can be determined with <a href="WinGet.htm">WinGet</a>. The Process command itself can also be used to discover a PID.</p>
      <p>Name: The name of a process is usually the same as its executable (without path), e.g. notepad.exe or winword.exe. Since a name might match multiple running processes, only the first process will be operated upon. The name is not case sensitive.</p></dd>

  <dt>Param3</dt>
  <dd><p>See <em>Cmd</em> above for details.</p></dd>

</dl>

<h3>ErrorLevel</h3>
<p>See <em>Cmd</em> above for details.</p>
<h3>Remarks</h3>
<p>For <em>Wait</em> and <em>WaitClose</em>: Processes are checked every 100 milliseconds; the moment the condition is satisfied, the command stops waiting. In other words, rather than waiting for the timeout  to expire, it immediately sets <a href="../misc/ErrorLevel.htm">ErrorLevel</a> as described above, then continues  execution of the script. Also, while the command is in a waiting state, new <a href="../misc/Threads.htm">threads</a> can be launched via <a href="../Hotkeys.htm">hotkey</a>, <a href="Menu.htm">custom menu item</a>, or <a href="SetTimer.htm">timer</a>.</p>

<h3>Related</h3>
<p><a href="Run.htm">Run</a>, <a href="WinGet.htm">WinGet</a>, <a href="WinClose.htm">WinClose</a>, <a href="WinKill.htm">WinKill</a>, <a href="WinWait.htm">WinWait</a>, <a href="WinWaitClose.htm">WinWaitClose</a>, <a href="WinExist.htm">IfWinExist</a></p>
<h3>Examples</h3>
<pre class="NoIndent"><em>; Example #1:</em>

Run Notepad.exe, , , NewPID
Process, priority, %NewPID%, High
MsgBox The newly launched notepad's PID is %NewPID%.</pre>
<p>&nbsp;</p>
<pre class="NoIndent"><em>; Example #2:</em>

Process, wait, Notepad.exe, 5.5
NewPID = %ErrorLevel%  <em>; Save the value immediately since ErrorLevel is often changed.</em>
if NewPID = 0
{
    MsgBox The specified process did not appear within 5.5 seconds.
    return
}
<em>; Otherwise:</em>
MsgBox A matching process has appeared (Process ID is %NewPID%).
Process, priority, %NewPID%, Low
Process, priority, , High  <em>; Have the script set itself to high priority.</em>
WinClose Untitled - Notepad
Process, WaitClose, %NewPID%, 5
if ErrorLevel <em>; The PID still exists.</em>
    MsgBox The process did not close within 5 seconds.</pre>
<p>&nbsp;</p>
<pre class="NoIndent"><em>; Example #3: A hotkey to change the priority of the active window's process:</em>

#z:: <em>; Win+Z hotkey</em>
WinGet, active_pid, PID, A
WinGetTitle, active_title, A
Gui, 5:Add, Text,, Press ESCAPE to cancel, or double-click a new`npriority level for the following window:`n%active_title%
Gui, 5:Add, ListBox, vMyListBox gMyListBox r5, Normal|High|Low|BelowNormal|AboveNormal
Gui, 5:Add, Button, default, OK
Gui, 5:Show,, Set Priority
return

5GuiEscape:
5GuiClose:
Gui, Destroy
return

MyListBox:
if A_GuiEvent &lt;&gt; DoubleClick
    return
<em>; else fall through to the next label:</em>
5ButtonOK:
GuiControlGet, MyListBox
Gui, Destroy
Process, Priority, %active_pid%, %MyListBox%
if ErrorLevel
    MsgBox Success: Its priority was changed to &quot;%MyListBox%&quot;.
else
    MsgBox Error: Its priority could not be changed to &quot;%MyListBox%&quot;.
return</pre>
<p>&nbsp;</p>
<pre class="NoIndent" id="ListEx"><em>; Example #4: Retrieves a list of running processes via DllCall then shows them in a MsgBox.</em>

d := "  |  "  <em>; string separator</em>
s := 4096  <em>; size of buffers and arrays (4 KB)</em>

Process, Exist  <em>; sets ErrorLevel to the PID of this running script</em>
<em>; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400)</em>
h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel, "Ptr")
<em>; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32)</em>
DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", t)
VarSetCapacity(ti, 16, 0)  <em>; structure of privileges</em>
NumPut(1, ti, 0, "UInt")  <em>; one entry in the privileges array...</em>
<em>; Retrieves the locally unique identifier of the debug privilege:</em>
DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
NumPut(luid, ti, 4, "Int64")
NumPut(2, ti, 12, "UInt")  <em>; enable this privilege: SE_PRIVILEGE_ENABLED = 2</em>
<em>; Update the privileges of this process with the new access token:</em>
r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", &amp;ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
DllCall("CloseHandle", "Ptr", t)  <em>; close this access token handle to save memory</em>
DllCall("CloseHandle", "Ptr", h)  <em>; close this process handle to save memory</em>

hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  <em>; increase performance by preloading the library</em>
s := VarSetCapacity(a, s)  <em>; an array that receives the list of process identifiers:</em>
c := 0  <em>; counter for process idendifiers</em>
DllCall("Psapi.dll\EnumProcesses", "Ptr", &amp;a, "UInt", s, "UIntP", r)
Loop, % r // 4  <em>; parse array for identifiers as DWORDs (32 bits):</em>
{
   id := NumGet(a, A_Index * 4, "UInt")
   <em>; Open process with: PROCESS_VM_READ (0x0010) | PROCESS_QUERY_INFORMATION (0x0400)</em>
   h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id, "Ptr")
   if !h
      continue
   VarSetCapacity(n, s, 0)  <em>; a buffer that receives the base name of the module:</em>
   e := DllCall("Psapi.dll\GetModuleBaseName", "Ptr", h, "Ptr", 0, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
   if !e    <em>; fall-back method for 64-bit processes when in 32-bit mode:</em>
      if e := DllCall("Psapi.dll\GetProcessImageFileName", "Ptr", h, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
         SplitPath n, n
   DllCall("CloseHandle", "Ptr", h)  <em>; close process handle to save memory</em>
   if (n &amp;&amp; e)  <em>; if image is not null add to list:</em>
      l .= n . d, c++
}
DllCall("FreeLibrary", "Ptr", hModule)  <em>; unload the library to free memory</em>
<em>;Sort, l, C  ; uncomment this line to sort the list alphabetically</em>
MsgBox, 0, %c% Processes, %l%</pre>
<p>&nbsp;</p>
<pre class="NoIndent" id="ListCom"><em>; Example #5: Retrieves a list of running processes via COM.</em>

Gui, Add, ListView, x2 y0 w400 h500, Process Name|Command Line
for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
    LV_Add("", process.Name, process.CommandLine)
Gui, Show,, Process List

<em>; Win32_Process: <a href="http://msdn.microsoft.com/en-us/library/aa394372.aspx">http://msdn.microsoft.com/en-us/library/aa394372.aspx</a></em>
</pre>

</body>
</html>
